package ar.com.gestion.tabla;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import java.util.LinkedList;
import java.util.List;

import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

import ar.com.gestion.dominio.Producto;

/**
 * Modelo de Apuntes. Cada fila es una Apunte y las columnas son los datos de la
 * Apunte. Implementa TableModel y dos métodos para añadir y eliminar Apuntes
 * del modelo
 */
public class ModeloTabla implements TableModel {

	/**
	 * Returns the number of columns in the model. A <code>JTable</code> uses
	 * this method to determine how many columns it should create and display by
	 * default.
	 * 
	 * @return the number of columns in the model
	 * @see #getRowCount
	 * 
	 */
	public int getColumnCount() {
		// Devuelve el número de columnas del modelo, que coincide con el
		// número de datos que tenemos de cada Apunte.
		return 11;

	}

	/**
	 * Returns the number of rows in the model. A <code>JTable</code> uses this
	 * method to determine how many rows it should display. This method should
	 * be quick, as it is called frequently during rendering.
	 * 
	 * @return the number of rows in the model
	 * @see #getColumnCount
	 * 
	 */
	public int getRowCount() {
		// Devuelve el número de Apuntes en el modelo, es decir, el número
		// de filas en la tabla.
		return datos.size();
	}

	/**
	 * Returns the value for the cell at <code>columnIndex</code> and
	 * <code>rowIndex</code>.
	 * 
	 * @param rowIndex
	 *            the row whose value is to be queried
	 * @param columnIndex
	 *            the column whose value is to be queried
	 * @return the value Object at the specified cell
	 * 
	 */
	public Object getValueAt(int rowIndex, int columnIndex) {
		Producto aux;

		// Se obtiene la Apunte de la fila indicada
		aux = (Producto) (datos.get(rowIndex));

		// Se obtiene el campo apropiado según el valor de columnIndex
		switch (columnIndex) {
		case 0:
			return aux.getId();
		case 1:
			return aux.getCodigo();
		case 2:
			return aux.getCantidad();
		case 3:
			return aux.getPrecio();
		case 4:
			return aux.getTipo();

		case 5:
			return aux.getMaterial();

		case 6:
			return aux.getTalle();

		case 7:
			return aux.getDescripcion();
		case 8:
			return aux.getColor();
		case 9:
			return aux.getModelo();
		case 10:
			return aux.getReservado();

		default:
			return null;
		}
	}

	/**
	 * Borra del modelo la Apunte en la fila indicada
	 */
	public void borraProducto(int fila) {
		// Se borra la fila
		datos.remove(fila);

		// Y se avisa a los suscriptores, creando un TableModelEvent...
		TableModelEvent evento = new TableModelEvent(this, fila, fila,
				TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE);

		// ... y pasándoselo a los suscriptores
		avisaSuscriptores(evento);
	}

	/**
	 * Añade una Apunte al final de la tabla
	 */
	public void anhadeProducto(Producto nuevaProducto) {
		// Añade la Apunte al modelo
		datos.add(nuevaProducto);

		// Avisa a los suscriptores creando un TableModelEvent...
		TableModelEvent evento;
		evento = new TableModelEvent(this, this.getRowCount() - 1,
				this.getRowCount() - 1, TableModelEvent.ALL_COLUMNS,
				TableModelEvent.INSERT);

		// ... y avisando a los suscriptores
		avisaSuscriptores(evento);
	}

	public void anhadeProductos(List<Producto> productos) {
		for (int i = 0; i < datos.size(); i++) {
			borraProducto(1);
		}

		for (Producto producto : productos) {
			anhadeProducto(producto);
		}

	}

	/**
	 * Adds a listener to the list that is notified each time a change to the
	 * data model occurs.
	 * 
	 * @param l
	 *            the TableModelListener
	 * 
	 */
	public void addTableModelListener(TableModelListener l) {
		// Añade el suscriptor a la lista de suscriptores
		listeners.add(l);
	}

	/**
	 * Returns the most specific superclass for all the cell values in the
	 * column. This is used by the <code>JTable</code> to set up a default
	 * renderer and editor for the column.
	 * 
	 * @param columnIndex
	 *            the index of the column
	 * @return the common ancestor class of the object values in the model.
	 * 
	 */
	public Class getColumnClass(int columnIndex) {
		// Devuelve la clase que hay en cada columna.
		switch (columnIndex) {
		case 0:
			// La columna cero contiene el nombre de la Apunte, que es
			// un String
			return int.class;
		case 1:
			// La columna uno contiene el apellido de la Apunte, que es
			// un String
			return String.class;
		case 2:
			// La columna dos contine la edad de la Apunte, que es un
			// Integer (no vale int, debe ser una clase)
			return float.class;

		case 3:
			return float.class;
		case 4:
			return String.class;
		case 5:
			return String.class;
		case 6:
			return float.class;
		case 7:
			return String.class;
		case 8:
			return String.class;
		case 9:
			return String.class;
		case 10:
			return int.class;

		default:
			// Devuelve una clase Object por defecto.
			return Object.class;
		}
	}

	/**
	 * Returns the name of the column at <code>columnIndex</code>. This is used
	 * to initialize the table's column header name. Note: this name does not
	 * need to be unique; two columns in a table can have the same name.
	 * 
	 * @param columnIndex
	 *            the index of the column
	 * @return the name of the column
	 * 
	 */
	public String getColumnName(int columnIndex) {
		// Devuelve el nombre de cada columna. Este texto aparecerá en la
		// cabecera de la tabla.
		switch (columnIndex) {
		case 0:
			return "Id Producto";
		case 1:
			return "Codigo";
		case 2:
			return "Cantidad";
		case 3:
			return "Precio";
		case 4:
			return "Tipo";
		case 5:
			return "Material";
		case 6:
			return "Talle";
		case 7:
			return "Descripcion";
		case 8:
			return "Color";
		case 9:
			return "Modelo";
		case 10:
			return "Reservado";
		default:
			return null;
		}
	}

	/**
	 * Returns true if the cell at <code>rowIndex</code> and
	 * <code>columnIndex</code> is editable. Otherwise, <code>setValueAt</code>
	 * on the cell will not change the value of that cell.
	 * 
	 * @param rowIndex
	 *            the row whose value to be queried
	 * @param columnIndex
	 *            the column whose value to be queried
	 * @return true if the cell is editable
	 * @see #setValueAt
	 * 
	 */
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		// Permite que la celda sea editable.
		return false;
	}

	/**
	 * Removes a listener from the list that is notified each time a change to
	 * the data model occurs.
	 * 
	 * @param l
	 *            the TableModelListener
	 * 
	 */
	public void removeTableModelListener(TableModelListener l) {
		// Elimina los suscriptores.
		listeners.remove(l);
	}

	/**
	 * Sets the value in the cell at <code>columnIndex</code> and
	 * <code>rowIndex</code> to <code>aValue</code>.
	 * 
	 * @param aValue
	 *            the new value
	 * @param rowIndex
	 *            the row whose value is to be changed
	 * @param columnIndex
	 *            the column whose value is to be changed
	 * @see #getValueAt
	 * @see #isCellEditable
	 * 
	 */
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
		// Obtiene la Apunte de la fila indicada
		Producto aux;
		aux = (Producto) (datos.get(rowIndex));

		// Cambia el campo de Apunte que indica columnIndex, poniendole el
		// aValue que se nos pasa.
		switch (columnIndex) {
		case 0:
			aux.setId((int) aValue);
			break;
		case 1:
			aux.setCodigo((String) aValue);
			break;
		case 2:
			aux.setCantidad(Integer.parseInt((String) aValue));
			break;
		case 3:
			aux.setPrecio((float) aValue);
			break;
		case 4:
			aux.setTipo((String) aValue);
			break;
		case 5:
			aux.setMaterial((String) aValue);
			break;
		case 6:
			aux.setTalle((float) aValue);
		case 7:
			aux.setDescripcion((String) aValue);
		case 8:
			aux.setColor((String) aValue);
		case 9:
			aux.setModelo((String) aValue);
		case 10:
			aux.setReservado((int) aValue);

		default:
			break;
		}

		// Avisa a los suscriptores del cambio, creando un TableModelEvent ...
		TableModelEvent evento = new TableModelEvent(this, rowIndex, rowIndex,
				columnIndex);

		// ... y pasándoselo a los suscriptores.
		avisaSuscriptores(evento);
	}

	/**
	 * Pasa a los suscriptores el evento.
	 */
	private void avisaSuscriptores(TableModelEvent evento) {
		int i;

		// Bucle para todos los suscriptores en la lista, se llama al metodo
		// tableChanged() de los mismos, pasándole el evento.
		for (i = 0; i < listeners.size(); i++) {
			((TableModelListener) listeners.get(i)).tableChanged(evento);
		}
	}

	public Producto getRowAt(int index) {
		return datos.get(index);
	}
	

	/**
	 * Lista con los datos. Cada elemento de la lista es una instancia de Apunte
	 */
	private LinkedList<Producto> datos = new LinkedList<Producto>();
	/**
	 * Lista de suscriptores. El JTable será un suscriptor de este modelo de
	 * datos
	 */
	private LinkedList listeners = new LinkedList();
}